﻿using System;
using System.Collections.Generic;
using System.Text;

namespace Acoris.Rendering
{

#if WIN2D

    using System.Numerics;
    using Windows.Foundation;
    using Microsoft.Graphics.Canvas;
    using Microsoft.Graphics.Canvas.Text;

    /// <summary>
    /// represents CanvasTextLayout Extensions method
    /// </summary>
    public static class CanvasTextLayoutExtensions
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="layout"></param>
        /// <returns></returns>
        public static Vector2 JustifyTextLayoutBounary(this CanvasTextLayout layout) {
            var width = 0f;
            var height = 0f;

            foreach (var lineCluster in layout.LineMetrics) {
                height += lineCluster.Height;
            }

            foreach (var metric in layout.ClusterMetrics) {
                width += metric.Width;
            }

            return new Vector2(width, height);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="format"></param>
        /// <returns></returns>
        public static Vector2 JustifyTextFormatWhitespaceSize(this CanvasTextFormat format,ICanvasResourceCreator sender) {
            Vector2 size;
            using (var textLayout = new CanvasTextLayout(sender, "\x20", format, 100, 100)) {
                size = textLayout.JustifyTextLayoutBounary();
            }
            return size;
        }

        /// <summary>
        /// 
        /// </summary>
        static void EvaluteTextLayout() {
            CanvasTextAnalyzer textAnalyzer = new CanvasTextAnalyzer(string.Empty, CanvasTextDirection.TopToBottomThenLeftToRight);

        }
    }

#endif


    /// <summary>
    /// represents a text-element
    /// </summary>
    public class TextElement : VisualElement {
        private string m_text;

#if WIN2D
        protected CanvasTextLayout TextLayout;
        protected CanvasTextFormat TextFormat;
#endif


        /// <summary>
        /// justify text layout 
        /// </summary>
        internal void EvaluatedJustifyTextElementActualSize() {
            if (TextLayout != null) {

                // justify
                var size = TextLayout.JustifyTextLayoutBounary();

                if (MaxWidth == VisualElement.Auto || MaxWidth <= size.X) {
                    MinWidth = MaxWidth = size.X;
#if WIN2D && NET_UWP
                    TextLayout.RequestedSize = size.ToSize();
#endif
                }
                else {
                    MinWidth = MaxWidth;
#if WIN2D && NET_UWP
                    TextLayout.RequestedSize = new Size(MaxWidth, size.Y);
#endif
                }

                // modify actual width and actual height properties

                ActualHeight = Height = MinHeight = size.Y;
                ActualWidth = Width = MinWidth;
            }
        }

        /// <summary>
        /// gets or sets Text
        /// </summary>
        public string Text {
            get { return m_text; }
            set {
                if (HasCached) {
                    Dispose();
                }
                BeginChange();
                m_text = value;
            }
        }

        /// <summary>
        /// gets or sets foreground brush
        /// </summary>
        public Brush Foreground { get; set; }

        /// <summary>
        /// gets or sets font family
        /// </summary>
        public string FontFamily { get; set; }

        /// <summary>
        /// gets or sets font size
        /// </summary>
        public float FontSize { get; set; }

        /// <summary>
        /// gets or sets font style
        /// </summary>
        public FontStyle FontStyle { get; set; }

        /// <summary>
        /// gets or sets font weight
        /// </summary>
        public float FontWeight { get; set; } = 400;

        /// <summary>
        /// gets or sets underline style
        /// </summary>
        public Underline Underline { get; set; }

        /// <summary>
        /// gets or sets character white space
        /// </summary>
        public float CharacterWhiteSpace { get; set; }

        /// <summary>
        /// gets or sets baseline height
        /// </summary>
        public float Baseline { get; set; } = .8f;

        /// <summary>
        /// gets or sets tab stop increment
        /// </summary>
        public float IncreamentTabStop { get; set; } = 4f;

        /// <summary>
        /// gets or sets before Whitespace count
        /// </summary>
        public float BeforeWhitespaceCount { get; set; }

        /// <summary>
        /// gets or sets after whitespace count
        /// </summary>
        public float AfterWhitespaceCount { get; set; }

        /// <summary>
        /// gets whitespace size
        /// </summary>
        public Vector2 WhitespaceSize { get; private set; }

        /// <summary>
        /// gets or sets max width
        /// </summary>
        public float MaxWidth { get; set; } = VisualElement.Auto;

        // text-element must be display all text or set visibility 
        // value collapsed
        // public float MaxHeight { get; set; }

        /// <summary>
        /// gets the text-element content
        /// </summary>
        /// <returns>return text-element content</returns>
        public override string ToString() {
            return m_text;
        }
    }


}
